/************************************************************
 * Copytight(C) Mike
 * 文件名：Macro.h
 * 作  者：Mike
 * 版  本：V3.0
 * 日  期：2021/02/19
 * 描  述：宏定义 头文件
 * 备  注：
************************************************************/
#ifndef __MACRO_H__
#define __MACRO_H__

/*******************************************************************************
* NOTE
* @ '#':字符串化运算符
* @ "##":连接运算符
********************************************************************************/

/*******************************************************************************
* 特殊意义常量
********************************************************************************/
#define 	SECONDS_PER_YEAR 	(60 * 60 * 24 * 365)UL
#define 	PI_PRO				3.141592653589793238462643383279502884197169
#define 	PI				 	3.1415927
#define		E					2.718281828459
#define		FI					1.618

/*******************************************************************************
* 位操作类
********************************************************************************/
/* Func:将二进制逻辑的十进制表示转换为真实值; Example:BIN（0101）== 5; */
#define 	BIN(n) \
					((0x##n##L) & (0x01 << 0*4)) >> 0*3 |\
					((0x##n##L) & (0x01 << 1*4)) >> 1*3 |\
					((0x##n##L) & (0x01 << 2*4)) >> 2*3 |\
					((0x##n##L) & (0x01 << 3*4)) >> 3*3 |\
					((0x##n##L) & (0x01 << 4*4)) >> 4*3 |\
					((0x##n##L) & (0x01 << 5*4)) >> 5*3 |\
					((0x##n##L) & (0x01 << 6*4)) >> 6*3 |\
					((0x##n##L) & (0x01 << 7*4)) >> 7*3

/* Func:用于指定位的置1或置0的标记数; Example:BIT(2) -> 0000 0100; */
#define  	BIT(n)				(0x01 << n)

/* Func:用于指定位的置位、复位; Example:SET_BIT(ODR,3) */
#define  	SET_BIT(x,n)		x |= BIT(n)
#define  	RESET_BIT(x,n)		x &= ~BIT(n)

/* Func: 获取指定字节数据; Example: ; */
#define	 	GET_BYTE(x,byte)	((x >> byte*4) & 0x000000ff)	/* 获取第BYTE个字节 */

/* Func: 获取指定比特位数据(状态); Example: ; */
#define	 	GET_BIT(x,n)		!(!(x & BIT(n)))	/* 获取第n位 */

/* Func: 获取连续比特位数据值; Example: ; */
#define  	BIT_M_TO_N(x,m,n)	((unsigned int)(x << (31-(n))) >> ((31 - (n)) + (m)))

/*******************************************************************************
* 算法类
********************************************************************************/
/* Func: 返回最小值; Example: ; */
#define  	MIN(A,B) 			( (A) <= (B) ? (A) : (B) )

/* Func: 返回最大值; Example: ; */
#define  	MAX(A,B) 			( (A) >= (B) ? (A) : (B) )

/* Func: 将一个字母转换为大写; Example: ; */
#define  	UP_CASE( c ) 		( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )

/* Func: 将一个字母转换为小写; Example: ; */
#define  	DOWM_CASE( c ) 		( ((c) >= 'A' && (c) <= 'Z') ? ((c) + 0x20) : (c) )

/* Func: 将一个字母转换为小写; Example: ; */
#define  	TOGGLE_CASE( c ) 	( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : \
								 (((c) >= 'A' && (c) <= 'Z') ? ((c) + 0x20) : (c))\
								)

#define 	SWAP(x, y) \
					do\
					{\
						(x)=(x)+(y);\
						(y)=(x)–(y);\
						(x)=(x)–(y);\
					}while(0)
/*******************************************************************************
* 优化类
********************************************************************************/
/* Func: 复合语句宏定义，利用do{}while(0)形式优化了语法问题; Example: ; */
#define 	FUN(arg) 	\
				do\
				{\
					something();\
				}while(0)

/* Func: 优化strcpy/strncpy越界问题，避免非法操作内存; Example: ; */
#define 	STRCPY(str1,str2)	strncpy(str1,str2,sizeof(str1)/sizeof(char))


/*******************************************************************************
* 如何用C语言实现读写寄存器变量？
********************************************************************************/
#define  REGISTER  (*(volatile unsigned long *)0x48000004)    

//（1）由于是寄存器地址，所以需要先将其强制类型转换为 ”volatile unsigned long *”。
//（2）由于后续需要对寄存器直接赋值，所以需要解引用。



#endif /* __MACRO_H__ */
/****************************************END OF FILE****************************************/
